﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Xml.Linq;

namespace SHomeWorkshop.LunarPresentation.Commands
{
    public partial class Command
    {
        /// <summary>
        /// 将当前公式添加为一个模板。
        /// </summary>
        /// <param name="cmdString">应传入自定义的命令文本（必须是全英文，分大小写）。命令不能与已存在的某个模板的命令重复。</param>
        public static bool ExTemplateAdd(string cmdString)
        {
            if (Globals.selectedEditor == null) return false;
            if (Globals.selectedEditor.SelectedExpression == null) return false;

            if (cmdString == null || cmdString.Length <= 0)
            {
                MessageBox.Show("请为新公式模板设置一个（纯字母组成的）字符串作为调用命令！\r\n\r\n" +
                    "自定义命令应跟随两个斜杠“//”之后。\r\n\r\n" +
                    "在将当前公式设置为模板后，可以使用“/(命令文本)”的格式(单斜框，括号不输入)来直接插入此模板！",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            LunarPresentation.Expressions.Expression curEx
                = Globals.selectedEditor.SelectedExpression;

            if (curEx is Expressions.SubPanel)
            {
                MessageBox.Show("子面板不能被设置为公式模板！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;//子面板不支持。
            }

            string templateFilePath = Globals.pathOfUserDirectory + "DefTemplates.xml";

            if (Globals.templateXDoc == null)
            {
                if (System.IO.File.Exists(templateFilePath))
                {
                    try
                    {
                        Globals.templateXDoc = XDocument.Load(templateFilePath);

                        if (Globals.templateXDoc.Root == null)
                        {
                            Globals.templateXDoc.Add(new XElement("Templates"));
                        }

                        if (Globals.templateXDoc.Root.Name.ToString() != "Templates")
                        {
                            Globals.templateXDoc.RemoveNodes();
                            Globals.templateXDoc.Add(new XElement("Templates"));
                        }
                    }
                    catch
                    {
                        try
                        {
                            System.IO.File.Delete(templateFilePath);

                            Globals.templateXDoc = new XDocument();
                            Globals.templateXDoc.Add(new XElement("Templates"));
                        }
                        catch (Exception ex)
                        {
                            Dialogs.LunarMsgBox.MsgBoxShow(
                                Globals.appName,
                                "发生意外，未能删除无效的模板文件！",
                                "异常信息如下：\r\n" + ex.Message,
                                ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return false;
                        }
                    }
                }
                else
                {
                    Globals.templateXDoc = new XDocument();
                    Globals.templateXDoc.Add(new XElement("Templates"));
                }
            }

            //看看命令文本是否重复。
            IEnumerable<XElement> xElements = Globals.templateXDoc.Root.Elements();
            foreach (XElement xe in xElements)
            {
                if (xe.Attribute("cmd").Value == cmdString)
                {
                    MessageBox.Show("定义的命令文本(" + cmdString + ")已被另一个公式模板使用。不能重复！",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return false;
                }
            }

            XElement newTemp = new XElement("Template");

            newTemp.SetAttributeValue("cmd", cmdString);
            newTemp.SetAttributeValue("Type", curEx.XmlData.GetAttribute("Type").Value);
            newTemp.Add(curEx.XmlData.OuterXml);

            Globals.templateXDoc.Root.Add(newTemp);

            Globals.templateXDoc.Save(templateFilePath);

            MessageBox.Show("当前公式已保存为公式模板。",
                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
            return true;
        }

        public static bool ExTemplateReadAndInsert(string cmdString)
        {
            if (cmdString == null || cmdString.Length <= 0)
            {
                MessageBox.Show("请输入公式模板的调用命令。格式如下：\r\n\r\n" +
                    "/(命令文本)\r\n\r\n" +
                    "★注意：⑴只以一个斜杠“/”开头；⑵括号不输入。",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }

            if (Globals.selectedEditor == null)
            {
                MessageBox.Show("当前未打开任何文档！",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }

            if (Globals.selectedEditor.SelectedExpression == null)
            {
                MessageBox.Show("请先选中一个公式作为插入模板公式的位置。",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }

            if (Globals.templateXDoc == null)
            {
                string templateFilePath = Globals.pathOfUserDirectory + "DefTemplates.xml";
                if (System.IO.File.Exists(templateFilePath))
                {
                    try
                    {
                        Globals.templateXDoc = XDocument.Load(templateFilePath);

                        if (Globals.templateXDoc.Root == null)
                        {
                            MessageBox.Show("当前尚未设置任何公式模板。",
                                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                            System.IO.File.Delete(templateFilePath);
                            return false;
                        }
                    }
                    catch (Exception ex)
                    {
                        Dialogs.LunarMsgBox.MsgBoxShow(
                            Globals.appName,
                            "公式模板文件读取异常（或未能删除无效模板文档）。",
                            "异常消息如下：\r\n" + ex.Message,
                            ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }
                }
                else
                {
                    MessageBox.Show("当前尚未设置任何公式模板。",
                                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                    return false;
                }
            }

            Expressions.Expression preExpression = null;

            Expressions.SubPanel sPanel = Globals.selectedEditor.SelectedExpression as Expressions.SubPanel;
            if (sPanel != null)
            {
                if (sPanel.BasePanel.Children.Count > 0)
                {
                    preExpression = sPanel.BasePanel.Children[sPanel.BasePanel.Children.Count - 1] as Expressions.Expression;
                }

                //否则还是null。
            }
            else
            {
                preExpression = Globals.selectedEditor.SelectedExpression;
            }

            if (preExpression == null)
            {
                MessageBox.Show("请先选择一个公式作为插入位置！", Globals.appName, MessageBoxButton.OK,
                    MessageBoxImage.Warning);
                return false;
            }

            IEnumerable<XElement> xElements = Globals.templateXDoc.Root.Elements();
            foreach (XElement xe in xElements)
            {
                if (xe.Attribute("cmd").Value == cmdString)
                {
                    try
                    {
                        TypeOfExpression destExType = (TypeOfExpression)Enum.Parse(typeof(TypeOfExpression),
                            xe.Attribute("Type").Value);
                        Expressions.Expression newEx = Command.InsertExpression(destExType, xe.Value);
                        return newEx != null;
                    }
                    catch (Exception ex)
                    {
                        Dialogs.LunarMsgBox.MsgBoxShow(
                            Globals.appName,
                            "载入模板文本串时出错。",
                            "异常信息如下：\r\n" + ex.Message,
                            ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }
                }
            }

            MessageBox.Show("未能在公式模板文件中找到与“" + cmdString + "”这个命令对应的公式模板。",
                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
            return false;
        }

        private static string ExTemplateRead(string cmdString)
        {
            return string.Empty;
        }
    }
}
